package org.rcy.framework.job.elastic.config;

import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperConfiguration;
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter;
import org.rcy.framework.job.elastic.CleanUnavailableServersJob;
import org.rcy.framework.job.elastic.JobManager;
import org.rcy.framework.job.elastic.JobShutdownHook;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableConfigurationProperties({JobProperties.class})
public class JobAutoConfiguration {
    public JobAutoConfiguration() {
    }

    @Bean(
            initMethod = "init",
            destroyMethod = "close"
    )
    public ZookeeperRegistryCenter regCenter(JobProperties jobProperties) {
        ZookeeperConfiguration zkConfig = new ZookeeperConfiguration(jobProperties.getZkConnectString(), jobProperties.getNamespace());
        zkConfig.setMaxRetries(jobProperties.getMaxRetries());
        return new ZookeeperRegistryCenter(zkConfig);
    }

    @Bean
    public JobManager jobManager(ZookeeperRegistryCenter regCenter, JobProperties jobProperties) {
        return new JobManager(regCenter, jobProperties.isDisabled(), jobProperties.isDisabledOverwrite());
    }

    @Bean
    @ConditionalOnProperty(
        prefix = JobProperties.PREFIX,
        name = {"clean-server-on-shutdown"},
        havingValue = "true",
        matchIfMissing = true
    )
    public JobShutdownHook jobShutdownHook(JobProperties jobProperties, JobManager jobManager) {
        return new JobShutdownHook(jobManager);
    }

    @Bean
    @ConditionalOnBean({JobShutdownHook.class})
    public ApplicationStartedListener applicationStartedListener(JobManager jobManager, JobShutdownHook jobShutdownHook) {
        return new ApplicationStartedListener(jobShutdownHook);
    }

    @Bean
    @ConditionalOnProperty(
        prefix = JobProperties.PREFIX,
        name = {"clean-unavailable-servers"},
        havingValue = "true",
        matchIfMissing = false
    )
    public CleanUnavailableServersJob cleanUnavailableServersJob(JobProperties jobProperties, ZookeeperRegistryCenter regCenter, JobManager jobManager) {
        CleanUnavailableServersJob job = new CleanUnavailableServersJob(jobProperties.getCleanUnavailableServersCron(), regCenter);
        jobManager.addJob(job);
        return job;
    }

    private static class ApplicationStartedListener implements ApplicationListener<ApplicationStartedEvent> {
        private JobShutdownHook jobShutdownHook;

        public ApplicationStartedListener(JobShutdownHook jobShutdownHook) {
            this.jobShutdownHook = jobShutdownHook;
        }

        public void onApplicationEvent(ApplicationStartedEvent event) {
            this.jobShutdownHook.addHook();
        }
    }
}